<script lang="ts" setup>
import { reactive, ref, onMounted } from 'vue'
import { NLayout, NLayoutSider, NLayoutHeader, NLayoutContent, NInput, NInputGroup, NScrollbar, NTree, NButton, NPopconfirm, NIcon, NSpace, NForm, NFormItem, NModal, NCard, useNotification } from 'naive-ui'
import type { TreeOption, FormInst, FormRules } from 'naive-ui'
import { ReloadOutlined } from '@vicons/antd'
import http from '@/tools/http'

const notification = useNotification()

type ZookeeperNode = {
    label: string
    path: string
    data?: string
    children?: string[]
}

const pattern = ref<string>("")
const currentNode = reactive<ZookeeperNode>({ label: "", path: "" })
const nodeTree = reactive<ZookeeperNode[] & TreeOption[]>([])
const formVisiable = ref<boolean>(false)
const title = ref<string>("")
const formRef = ref<FormInst | null>(null)

const formData = reactive<ZookeeperNode>({
    label: "",
    path: "",
    data: ""
})

const formRules: FormRules = ({
    path: {
        required: true,
        message: '请输入节点名称',
        trigger: ['input']
    }
})

onMounted(() => {
    nodeTree.push({
        label: "/",
        path: "/",
        isLeaf: false
    })
    openNode({ path: "/" })
})

function reset() {
    nodeTree.length = 0;
    nodeTree.push({
        label: "/",
        path: "/",
        isLeaf: false
    })

}

function treeNodeClicked(info: { option: TreeOption }) {
    return {
        onClick: () => {
            openNode(info.option)
        }
    }
}

function openAdd() {
    formVisiable.value = true
    title.value = "添加节点"
    if (currentNode.path === "/") {
        formData.path = currentNode.path
    } else {
        formData.path = currentNode.path + '/'
    }
    formData.data = ""
}

function openUpdate() {
    formVisiable.value = true
    title.value = "编辑节点"
    formData.path = currentNode.path
    formData.data = currentNode.data
}

function openNode(node: ZookeeperNode | TreeOption) {
    const request = {
        path: node.path
    }
    http.post("/system/zookeeper/node", request).then(({ data }) => {
        if (data.code === "0") {
            currentNode.path = data.data.path
            currentNode.data = data.data.data
        }
    })
}

function getChildren(node: TreeOption | ZookeeperNode) {
    return new Promise<void>((resolve) => {
        const request = {
            path: node.path
        }
        http.post("/system/zookeeper/node/children", request).then(({ data }) => {
            if (data.code === "0") {
                let slash = "/"
                if (node.path === "/") {
                    slash = ""
                }
                const children: ZookeeperNode | TreeOption[] = []
                for (let i = 0; i < data.data.length; i++) {
                    children.push({
                        label: data.data[i],
                        path: node.path + slash + data.data[i],
                        data: "",
                        isLeaf: false
                    })
                }
                node.children = children
                resolve()
            }
        })
    })
}

function addNode() {
    http.post("/system/zookeeper/node/create", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '添加成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            console.log(formData)
            reset()
        }
    })
}

function updateNode() {
    http.post("/system/zookeeper/node/update", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '编辑成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            openNode({ path: formData.path })
        }
    })
}

function deleteNode() {
    const request = {
        path: currentNode.path
    }
    http.post("/system/zookeeper/node/delete", request).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '删除成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            reset()
        }
    })
}

function submit() {
    formRef.value?.validate((errors) => {
        if (!errors) {
            if (title.value === "添加节点") {
                addNode()
            } else {
                updateNode()
            }
            formVisiable.value = false
        }
    })
}
</script>
<template>
    <div class="flame-container">
        <n-layout has-sider position="absolute">
            <n-layout-sider content-style="padding: 6px;" bordered>
                <div style="position:relative;display: flex;height:34px;margin-bottom: 6px;">
                    <n-input-group>
                        <n-input v-model:value="pattern" placeholder="请输入关键字查询" clearable />
                        <n-button style="width:35px" @click="reset()">
                            <template #icon>
                                <n-icon><reload-outlined /></n-icon>
                            </template>
                        </n-button>
                    </n-input-group>
                </div>
                <div style="position: absolute;top:46px;bottom:6px;left:0;right:0">
                    <n-scrollbar style="max-height: 100%" trigger="none" x-scrollable>
                        <n-tree :show-irrelevant-nodes="false" key-field="path" :node-props="treeNodeClicked"
                            :pattern="pattern" :data="nodeTree" block-line :on-load="getChildren" />
                    </n-scrollbar>
                </div>
            </n-layout-sider>
            <n-layout position="absolute" style="left:272px;">
                <n-layout-header style="height: 48px;display: flex;justify-content: space-between;padding: 0 12px;"
                    bordered>
                    <div style="height:100%;display: flex;align-items: center;">
                        当前节点：{{ currentNode.path }}
                    </div>
                    <div style="height:100%;display: flex;align-items: center;">
                        <n-space>
                            <n-button @click="openNode({ path: currentNode.path })">刷新数据</n-button>
                            <n-button @click="openAdd">添加节点</n-button>
                            <n-button @click="openUpdate">编辑节点</n-button>
                            <n-popconfirm @positive-click="deleteNode">
                                <template #trigger>
                                    <n-button>删除节点</n-button>
                                </template>
                                确定删除该节点吗？
                            </n-popconfirm>
                        </n-space>
                    </div>
                </n-layout-header>
                <div style="position:absolute;top:48px;bottom:0;left:0;right:0">
                    <n-layout-content style="height:100%;padding: 12px;">
                        <div style="position:relative;height:30px;">
                            节点数据：
                        </div>
                        <div style="position:absolute;top:42px;left: 12px;right:12px;bottom:12px;word-wrap:break-word;">
                            <n-scrollbar style="max-height: 100%" trigger="none">
                                {{ currentNode.data }}
                            </n-scrollbar>
                        </div>
                    </n-layout-content>
                </div>
            </n-layout>
        </n-layout>
    </div>
    <n-modal v-model:show="formVisiable">
        <n-card style="width: 400px;" :title="title" :bordered="false">
            <n-form ref="formRef" :model="formData" :rules="formRules">
                <n-form-item label="节点名称" path="path">
                    <n-input v-model:value="formData.path" :disabled="title === '编辑节点'" placeholder="请输入节点名称" clearable />
                </n-form-item>
                <n-form-item label="节点数据">
                    <n-input type="textarea" v-model:value="formData.data" placeholder="请输入节点数据" clearable />
                </n-form-item>
            </n-form>
            <template #footer>
                <n-space justify="end">
                    <n-button attr-type="button" @click="formVisiable = false">取消</n-button>
                    <n-button attr-type="button" @click="submit()">提交</n-button>
                </n-space>
            </template>
        </n-card>
    </n-modal>
</template>
<style scoped></style>